﻿using System.Windows;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Utils;

namespace MugenMvvmToolkit
{
    /// <summary>
    ///     Represents the base class for Mvvm application.
    /// </summary>
    public abstract class MvvmApplication : Application
    {
        #region Fields

        private static IBootstrapper _bootstrapper;

        #endregion

        #region Constructor

        /// <summary>
        ///     Initializes a new instance of the <see cref="MvvmApplication" /> class.
        /// </summary>
        protected MvvmApplication()
        {
// ReSharper disable once DoNotCallOverridableMethodsInConstructor
            PhoneApplicationService = CreatePhoneApplicationService();
            PhoneApplicationService.Launching += OnLaunching;
            PhoneApplicationService.Activated += OnActivated;
            PhoneApplicationService.Deactivated += OnDeactivated;
            PhoneApplicationService.Closing += OnClosing;
            ApplicationLifetimeObjects.Add(PhoneApplicationService);
        }

        #endregion

        #region Properties

        /// <summary>
        ///     Gets the phone application service.
        /// </summary>
        public static PhoneApplicationService PhoneApplicationService { get; private set; }

        /// <summary>
        ///     Gets the <see cref="IBootstrapper" /> for the current <see cref="MvvmApplication" />.
        /// </summary>
        public static IBootstrapper Bootstrapper
        {
            get { return _bootstrapper; }
            private set
            {
                Should.PropertyBeNotNull(value, "Bootstrapper");
                _bootstrapper = value;
            }
        }

        /// <summary>
        ///     Provides easy access to the root frame of the Phone Application.
        /// </summary>
        /// <returns>The root frame of the Phone Application.</returns>
        public static PhoneApplicationFrame RootFrame { get; set; }

        #endregion

        #region Methods

        /// <summary>
        ///     Raises the PhoneApplicationService startup event.
        ///     Code to execute when the application is launching (eg, from Start)
        ///     This code will not execute when the application is reactivated
        /// </summary>
        protected virtual void OnLaunching(object sender, LaunchingEventArgs launchingEventArgs)
        {
            Bootstrapper = GetBootstrapper();
            if (!Bootstrapper.IsStarted)
                Bootstrapper.Start();
        }

        /// <summary>
        ///     Raises the PhoneApplicationService activated event.
        ///     Code to execute when the application is activated (brought to foreground)
        ///     This code will not execute when the application is first launched
        /// </summary>
        protected virtual void OnActivated(object sender, ActivatedEventArgs activatedEventArgs)
        {
        }

        /// <summary>
        ///     Raises the PhoneApplicationService deactivated event.
        ///     Code to execute when the application is deactivated (sent to background)
        ///     This code will not execute when the application is closing
        /// </summary>
        protected virtual void OnDeactivated(object sender, DeactivatedEventArgs deactivatedEventArgs)
        {
        }

        /// <summary>
        ///     Raises the PhoneApplicationService exit event.
        ///     Code to execute when the application is closing (eg, user hit Back)
        ///     This code will not execute when the application is deactivated
        /// </summary>
        protected virtual void OnClosing(object sender, ClosingEventArgs closingEventArgs)
        {
            if (Bootstrapper != null)
                Bootstrapper.Stop();
        }

        /// <summary>
        ///     Creates an instance of <see cref="PhoneApplicationService" />.
        /// </summary>
        /// <returns>An instance of <see cref="PhoneApplicationService" />.</returns>
        protected virtual PhoneApplicationService CreatePhoneApplicationService()
        {
            return new PhoneApplicationService();
        }

        /// <summary>
        ///     Gets the <see cref="IBootstrapper" /> for the current <see cref="MvvmApplication" />.
        /// </summary>
        /// <returns>
        ///     An instance of <see cref="IBootstrapper" />.
        /// </returns>
        protected abstract IBootstrapper GetBootstrapper();

        #endregion
    }
}